package com.zyl.blog.tasks.web.controller;

import com.zyl.blog.common.domain.task.vo.TaskOperationResult;
import com.zyl.blog.common.domain.task.vo.TaskVO;
import com.zyl.blog.common.response.Result;
import com.zyl.blog.tasks.enums.TaskType;
import com.zyl.blog.tasks.model.TaskScheduleUpdateVO;
import com.zyl.blog.tasks.schedule.abstracts.AbstractScheduledTask;
import com.zyl.blog.tasks.schedule.manager.TaskManager;
import lombok.RequiredArgsConstructor;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 任务控制器（增强版）
 * 包含单任务操作、批量操作和调度策略调整功能
 * @version v1.0
 * @ProjectName: Personal_Blog_Server
 * @Package: com.zyl.blog.tasks.web.controller
 * @ClassName: TaskController
 * @Author FinalFantasy
 * @Date 2025/8/12-14:52
 */
@RequiredArgsConstructor
@RestController
@RequestMapping("/tasks")
public class TaskController {

    private final TaskManager taskManager;

    // ==================== 原有单任务接口 ====================

    /**
     * 获取用户的所有任务
     */
    @GetMapping("/list")
    public Result<List<TaskVO>> getUserTasks(
            @RequestParam String username
    ) {
        return Result.ok(
                taskManager.getUserTasks(username).stream()
                        .map(this::convertToVO)
                        .collect(Collectors.toList())
        );
    }

    /**
     * 启动任务
     */
    @PostMapping("/start")
    public Result<TaskOperationResult> startTask(
            @RequestParam String taskName,
            @RequestParam String username
    ) {
        return Result.ok(taskManager.startTask(taskName, username));
    }

    /**
     * 暂停任务
     */
    @PostMapping("/pause")
    public Result<TaskOperationResult> pauseTask(
            @RequestParam String taskName,
            @RequestParam String username
    ) {
        return Result.ok(taskManager.pauseTask(taskName, username));
    }

    /**
     * 销毁任务
     */
    @DeleteMapping("/delete")
    public Result<TaskOperationResult> destroyTask(
            @RequestParam String taskName,
            @RequestParam String username
    ) {
        return Result.ok(taskManager.destroyTask(taskName, username, false));
    }

    /**
     * 恢复已删除的任务
     */
    @PostMapping("/restore")
    public Result<TaskOperationResult> restoreTask(
            @RequestParam String taskName,
            @RequestParam String username) {
        return Result.ok(taskManager.restoreTask(taskName, username));
    }

    /**
     * 获取用户的所有任务（包括已删除的）
     */
    @GetMapping("/all")
    public Result<List<TaskVO>> getAllUserTasks(
            @RequestParam String username,
            @RequestParam(required = false, defaultValue = "false") boolean includeDeleted
    ) {
        if (includeDeleted) {
            return Result.ok(
                    taskManager.getUserAllTasks(username).stream()
                            .map(this::convertToVO)
                            .collect(Collectors.toList())
            );
        }
        return getUserTasks(username);
    }

    /**
     * 重新加载任务
     */
    @PostMapping("/reload")
    public Result<TaskOperationResult> reloadTask(
            @RequestParam String taskName,
            @RequestParam String username
    ) {
        return Result.ok(taskManager.reloadTask(taskName, username));
    }

    /**
     * 检查任务是否正在运行
     */
    @GetMapping("/running")
    public Result<Boolean> isTaskRunning(
            @RequestParam String taskName,
            @RequestParam String username) {
        return Result.ok(taskManager.isTaskRunning(taskName, username));
    }

    // ==================== 新增批量操作接口 ====================

    /**
     * 批量启动任务
     * @param username 用户名
     * @param taskNames 任务名称列表
     * @return 每个任务的操作结果
     */
    @PostMapping("/batch/start")
    public Result<Map<String, TaskOperationResult>> batchStartTasks(
            @RequestParam String username,
            @RequestBody List<String> taskNames
    ) {
        Assert.notEmpty(taskNames, "任务名称列表不能为空");
        Map<String, TaskOperationResult> results = taskManager.batchStartTasks(taskNames, username);
        return Result.ok(results);
    }

    /**
     * 批量暂停任务
     */
    @PostMapping("/batch/pause")
    public Result<Map<String, TaskOperationResult>> batchPauseTasks(
            @RequestParam String username,
            @RequestBody List<String> taskNames
    ) {
        Assert.notEmpty(taskNames, "任务名称列表不能为空");
        Map<String, TaskOperationResult> results = taskManager.batchPauseTasks(taskNames, username);
        return Result.ok(results);
    }

    /**
     * 批量销毁任务（逻辑删除）
     */
    @PostMapping("/batch/delete")
    public Result<Map<String, TaskOperationResult>> batchDestroyTasks(
            @RequestParam String username,
            @RequestBody List<String> taskNames
    ) {
        Assert.notEmpty(taskNames, "任务名称列表不能为空");
        Map<String, TaskOperationResult> results = taskManager.batchDestroyTasks(taskNames, username);
        return Result.ok(results);
    }

    /**
     * 批量恢复任务
     */
    @PostMapping("/batch/restore")
    public Result<Map<String, TaskOperationResult>> batchRestoreTasks(
            @RequestParam String username,
            @RequestBody List<String> taskNames
    ) {
        Assert.notEmpty(taskNames, "任务名称列表不能为空");
        Map<String, TaskOperationResult> results = taskManager.batchRestoreTasks(taskNames, username);
        return Result.ok(results);
    }

    /**
     * 一键启动所有任务
     */
    @PostMapping("/all/start")
    public Result<Map<String, TaskOperationResult>> startAllTasks(
            @RequestParam String username
    ) {
        Map<String, TaskOperationResult> results = taskManager.startAllTasks(username);
        return Result.ok(results);
    }

    /**
     * 一键暂停所有任务
     */
    @PostMapping("/all/pause")
    public Result<Map<String, TaskOperationResult>> pauseAllTasks(
            @RequestParam String username
    ) {
        Map<String, TaskOperationResult> results = taskManager.pauseAllTasks(username);
        return Result.ok(results);
    }


    // ==================== 新增调度策略调整接口 ====================

    /**
     * 调整任务调度策略（支持CRON/固定速率/固定延迟切换）
     */
    @PostMapping("/update-schedule")
    public Result<TaskOperationResult> updateTaskSchedule(
            @RequestBody TaskScheduleUpdateVO updateVO
    ) {
        /* 参数校验 */
        validateScheduleParams(updateVO);

        TaskOperationResult result = taskManager.updateTaskSchedule(
                updateVO.getTaskName(),
                updateVO.getUsername(),
                updateVO.getScheduleType(),
                updateVO.getCronExpression(),
                updateVO.getInterval(),
                updateVO.getTimeUnit()
        );
        return Result.ok(result).msg("调度策略已更新");
    }


    /**
     * 转换任务对象为VO
     */
    private TaskVO convertToVO(AbstractScheduledTask task) {
        return new TaskVO()
                .setTaskName(task.getTaskName())
                .setTaskDescription(task.getTaskDescription())
                .setScheduleType(task.getScheduleType().name())
                .setCronExpression(task.getCronExpression())
                .setInterval(task.getTaskInterval())
                .setTimeUnit(task.getTimeUnit().name())
                .setUsername(task.getUsername())
                .setClassName(task.getClassName())
                .setRunning(taskManager.isTaskRunning(task.getTaskName(), task.getUsername()));
    }

    /**
     * 验证调度策略参数合法性
     */
    private void validateScheduleParams(TaskScheduleUpdateVO updateVO) {
        TaskType type = updateVO.getScheduleType();
        Assert.notNull(type, "调度类型不能为空");

        switch (type) {
            case CRON:
                Assert.hasText(updateVO.getCronExpression(), "CRON表达式不能为空");
                /* 可添加CRON表达式格式校验（使用Spring的CronExpression类） */
                break;
            case FIXED_RATE:
            case FIXED_DELAY:
                Assert.notNull(updateVO.getInterval(), "时间间隔不能为空");
                Assert.isTrue(updateVO.getInterval() > 0, "时间间隔必须大于0");
                Assert.notNull(updateVO.getTimeUnit(), "时间单位不能为空");
                break;
            default:
                throw new IllegalArgumentException("不支持的调度类型: " + type);
        }
    }
}

